package com.example.demo.tokenbucket;

import com.example.demo.redis.RedisUtil;
import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
@RequestMapping("/token/bucket")
public class TokenBucketController {
    @Resource
    RedisUtil redisUtil;

    @SneakyThrows
    @GetMapping("/flow/control")
    public String flowControl() {
        //先获取令牌 如果令牌数量大于1 ，才可以被执行，同时减少令牌数量
        //redis单个操作是原子的，但是多个操作不是，所以要确保一致性
        //使用lua脚本执行
        String LUA_SCRIPT =
                "local currentValue = redis.call('GET', KEYS[1]); " +
                        "if tonumber(currentValue) > 1 then " +
                        "   redis.call('SET', KEYS[1], tonumber(currentValue) - 1); " +
                        "   return redis.call('GET', KEYS[1]); " +  // 返回1表示操作成功
                        "else " +
                        "   return 0; " +  // 返回0表示不处理
                        "end";
        String result;
        Long canToken = redisUtil.exeLua(LUA_SCRIPT, "token");
        if (canToken != 0) {
            result = "抢到令牌，可以执行，剩余令牌个数" + canToken;
        } else {
            result = "未抢到令牌，降级方案，剩余令牌个数" + canToken;
        }
        return result;
    }
}
